/*******************************************************************************
 * *
 * *             COPYRIGHT 2012 CLEARLEAP, INC. ALL RIGHTS RESERVED.
 * *             CLEARLEAP CONFIDENTIAL PROPRIETARY
 * *             TEMPLATE VERSION R01.00
 * *
 * ********************************************************************************
 * *
 * *  FILE NAME: SAMLUtil.java
 * *
 * *---------------------------------- PURPOSE ------------------------------------
 * *
 * * Define utilities to prepare SAML Request message: loading message from template file, inflate/deflate the message
 * * encode/decode request message
 * *
 * *----------------------------- REVISION HISTORY --------------------------------
 * *
 * * Date      ID        Tracking#      Description
 * * --------  --------  -------------  -------------------------------------------
 * * 01.07                              Created
 * *
 * *--------------------------- INCLUDES ----------------------------*
 * *
 ******************************************************************************/
package com.easysale.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import org.apache.commons.codec.binary.Base64;
import org.xml.sax.SAXException;

/**
 * This utility class is used across the various servlets that make up the
 * SAML-based Single Sign-On Reference Tool. It includes various helper methods
 * that are used for the SAML transactions.
 *
 */
public class SAMLUtil {
    protected static Logger logger = Logger.getLogger("AuthenticateManager");
    public static final String SUCCESS_CODE = "urn:oasis:names:tc:SAML:2.0:status:Success";

    public static String loadSAMLRequest(String filePath, String providerName,
            String providerId, String assertionURL, String spnameQualifier)
            throws Exception {

        String samlRequestTemplate = ClearleapUtil.readFileContents(filePath);

        samlRequestTemplate = samlRequestTemplate.replace("PROVIDER_NAME",
                providerName);
        samlRequestTemplate = samlRequestTemplate.replace("ACS_URL",
                assertionURL);
        samlRequestTemplate = samlRequestTemplate.replace("AUTHN_ID",
                ClearleapUtil.createID());
        samlRequestTemplate = samlRequestTemplate.replace("ISSUE_INSTANT",
                ClearleapUtil.getDateAndTime());
        samlRequestTemplate = samlRequestTemplate.replace("PROVIDER_ID",
                providerId);
        samlRequestTemplate = samlRequestTemplate.replace("SPNAME_QUALIFIER",
                spnameQualifier);

        return samlRequestTemplate;
    }

    /**
     *
     * @param filePath
     * @param nameId
     * @param resourceId
     * @param action
     * @param ipAddress
     * @return
     * @throws Exception
     */
    public static String loadAuthzRequest(String filePath, String nameId,
            String resourceId, String action, String ipAddress)
            throws Exception {
        String samlRequestTemplate = ClearleapUtil.readFileContents(filePath);

        samlRequestTemplate = samlRequestTemplate.replace("AUTHZ_ID",
                ClearleapUtil.createID());
        samlRequestTemplate = samlRequestTemplate.replace("ISSUE_INSTANT",
                ClearleapUtil.getDateAndTime());
        samlRequestTemplate = samlRequestTemplate.replace("NAME_ID", nameId);
        samlRequestTemplate = samlRequestTemplate.replace("RESOURCE_ID",
                resourceId);
        samlRequestTemplate = samlRequestTemplate.replace("ACTION", action);
        samlRequestTemplate = samlRequestTemplate.replace("IP_ADDRESS",
                ipAddress);

        return samlRequestTemplate;
    }

    /**
     * Decode the SAML Response from GET request.
     *
     * @param samlString
     * @return
     * @throws DataFormatException
     * @throws IOException
     * @throws SAXException
     */
    public static String decodeSAMLResponseFromGet(String samlString)
            throws DataFormatException, IOException, SAXException {
        // Decode the Base64-encoded string and inflate it.
        String decodedMessage = samlString;
        decodedMessage = decodedMessage.replaceAll("^\\s+", "");
        decodedMessage = decodedMessage.replaceAll("\\s+", "");
        decodedMessage = decodedMessage.replace("^M", ""); // newline character
                                                            // that sometimes
                                                            // shows up in the
                                                            // HBO's logout
                                                            // request

        // decodedMessage = URLDecoder.decode(decodedMessage, "UTF-8");
        byte[] base64DecodedByteArray = Base64.decodeBase64(decodedMessage);

        Inflater inflater = new Inflater();
        InflaterInputStream iis = new InflaterInputStream(
                new ByteArrayInputStream(base64DecodedByteArray), inflater);
        ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
        int b;
        while ((b = iis.read()) != -1) {
            bout.write(b);
        }
        iis.close();
        bout.close();

        return new String(bout.toByteArray());
    }

    /**
     * Decode the SAML Response from POST request.
     *
     * @param samlString
     * @return
     * @throws DataFormatException
     * @throws IOException
     * @throws SAXException
     */
    public static String decodeSAMLResponseFromPost(String samlString)
            throws DataFormatException, IOException, SAXException {
        // Decode the Base64-encoded string
        byte[] samlBytes = Base64.decodeBase64(samlString.getBytes("UTF-8"));

        String decodedResponse = new String(samlBytes, 0, samlBytes.length,
                "UTF-8");

        return decodedResponse;
    }

}
